package com.lyfy.sd.order.mycat;

import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.util.Collection;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author: 谢星星
 * @date: 2022/9/10 19:23
 * @description:
 */
public class MyCatMurmurShardingAlgorithm implements StandardShardingAlgorithm<String> {
    private int seed = 0;
    private int datasourceCount;
    private int virtualBucketTimes = 160;
    private static final String TYPE = "MYCAT_MURMUR";
    private PartitionByMurmurHash partitionByMurmurHash;

    public MyCatMurmurShardingAlgorithm() {
        initPartitioner();
    }

    public MyCatMurmurShardingAlgorithm(int seed, int datasourceCount, int virtualBucketTimes) {
        this.seed = seed;
        this.datasourceCount = datasourceCount;
        this.virtualBucketTimes = virtualBucketTimes;
        initPartitioner();
    }

    private void initPartitioner() {
        partitionByMurmurHash = new PartitionByMurmurHash();
        partitionByMurmurHash.setSeed(seed);
        partitionByMurmurHash.setCount(datasourceCount);
        partitionByMurmurHash.setVirtualBucketTimes(virtualBucketTimes);
        partitionByMurmurHash.init();
    }

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
        String value = String.valueOf(shardingValue.getValue());
        int shardMod = partitionByMurmurHash.calculate(getNumber(value));
        for (String database : availableTargetNames) {
            if (database.endsWith(String.valueOf(shardMod))) {
                return database;
            }
        }
        throw new RuntimeException("Can not get available database.");
    }

    String getNumber(String str) {
        String regEx = "[^0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("0").trim();
    }

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<String> shardingValue) {
        return availableTargetNames;
    }

    public void init() {
        System.out.println("MyCatMurmurShardingAlgorithm init.");
    }

    @Override
    public String getType() {
        return TYPE;
    }

    @Override
    public Properties getProps() {
        return null;
    }

    @Override
    public void init(Properties properties) {
    }
}
